package eb;

import dao.MessageWriter;
import view.ClientGUI;

public class EncryptedInfo3 extends AgentInfo {
    private final MessageWriter writer;
    private static char[] passTable = new char[10 + 26 + 26];

    public EncryptedInfo3(MessageWriter writer) {
        this.writer = writer;
        initPassTable();
    }

    @Override
    public void log(String lastNm, String firstNm, String code) {
        if (!isValidAgentName(lastNm) || !isValidAgentName(firstNm)) {
            System.out.println("Invalid agent name. Only English characters are allowed.");
            System.exit(1);
        }

        if (!isValidCode(code)) {
            System.out.println("Invalid agent code. Only English characters and numbers are allowed.");
            System.exit(1);
        }

        String fName = encryptName(firstNm);
        ClientGUI.resultTxt.append("Encrypted agent first name: " + fName + "\n");
        String lName = encryptName(lastNm);
        ClientGUI.resultTxt.append("Encrypted agent last name: " + lName + "\n");
        String codeStr = encryptCode(code);
        ClientGUI.resultTxt.append("Encrypted agent code: " + codeStr + "\n\n");
        try {
            writer.logMsg(lName, fName, codeStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initPassTable() {
        for (char i = '0'; i <= '9'; ++i) {
            passTable[getIndex(i)] = (char) ((i + 1 - '0') % 10 + '0');
        }

        for (char i = 'A'; i <= 'Z'; ++i) {
            passTable[getIndex(i)] = (char) ((i + 1 - 'A') % 26 + 'A');
            passTable[getIndex((char) (i + 32))] = (char) ((i + 32 + 1 - 'a') % 26 + 'a');
        }
    }

    private String encryptName(String msg) {
        char[] cipher = new char[msg.length()];
        for (int i = 0; i < msg.length(); ++i) {
            char ch = msg.charAt(i);
            cipher[i] = Character.isLetterOrDigit(ch) ? passTable[getIndex(ch)] : ch;
        }
        return new String(cipher);
    }

    private String encryptCode(String code) {
        char[] cipher = new char[code.length()];
        for (int i = 0; i < code.length(); ++i) {
            char ch = code.charAt(i);
            cipher[i] = Character.isLetterOrDigit(ch) ? passTable[getIndex(ch)] : ch;
        }
        return new String(cipher);
    }

    private int getIndex(char ch) {
        if (Character.isDigit(ch)) {
            return ch - '0';
        }
        if (Character.isUpperCase(ch)) {
            return ch - 'A' + 10;
        }
        if (Character.isLowerCase(ch)) {
            return ch - 'a' + 10 + 26;
        }
        return -1;
    }
}
